package br.com.pentagrama.service.impl;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;

import br.com.pentagrama.dto.NomeParametro;
import br.com.pentagrama.dto.Parametros;
import br.com.pentagrama.service.ILog;
import br.com.pentagrama.util.Sistema;

public abstract class PingGenerico {

	private long timeoutInSeconds = 10000l;

	public boolean isReachable(String host) {
		ILog log = Sistema.getLog();
		Parametros parametros = Parametros.getInstance();
		String quantidadePing = parametros.getChaveParametro().get(NomeParametro.VEZES_TESTE_PING);
		boolean resultado = false;
		
//		try {
//			log.debug(Level.INFO, "Tentativa de isReachable - inativo");
//			boolean acessado = InetAddress.getByName(host).isReachable(1000);
//			if(acessado) {
//				log.info("Ping - endereço atingido: " + host);
//				return true;
//			}
//		} catch (UnknownHostException e1) {
//			return false;
//		} catch (IOException e1) {
//			return false;
//		}
		
		try {
			log.debug(Level.INFO, "Tentativa de ping pelo SO");
			String sistemaOperacional = System.getProperty("os.name");
			String comando = null;
			if(sistemaOperacional.toUpperCase().indexOf("WINDOWS") >= 0) {
				log.debug(Level.INFO, "SO: " + sistemaOperacional);
				comando = "ping -n " + quantidadePing + " " + host;
			} else {
				log.debug(Level.INFO, "SO: " + sistemaOperacional);
				comando = "ping -c " + quantidadePing + " " + host;
			}
			
			resultado = executeCommandLine(comando, false, false, timeoutInSeconds);
		} catch (Exception e) {
			resultado = false;
		}
		
		if(resultado) {
			String msgLog1 = "Ping - endere\u00E7o alcan\u00E7ado: " + host;
			log.debug(Level.INFO, msgLog1);
			log.info(msgLog1);
		} else {
			String msgLog1 = "Ping - endere\u00E7o inacess\u00EDvel: " + host;
			log.debug(Level.INFO, msgLog1);
			log.alerta(msgLog1);
		}
		return resultado;

	}

	public static boolean executeCommandLine(final String commandLine,
			final boolean printOutput, final boolean printError,
			final long timeout) throws IOException, InterruptedException,
			TimeoutException {
		Runtime runtime = Runtime.getRuntime();
		Process process = runtime.exec(commandLine);

		Worker worker = new Worker(process);
		worker.start();
		try {
			worker.join(timeout);
			if (worker.exit != null)
				return worker.exit == 0;
			else
				throw new TimeoutException();
		} catch (InterruptedException ex) {
			worker.interrupt();
			Thread.currentThread().interrupt();
			throw ex;
		} finally {
			process.destroy();
		}
	}

	private static class Worker extends Thread {
		private final Process process;
		private Integer exit;

		private Worker(Process process) {
			this.process = process;
		}

		public void run() {
			try {
				exit = process.waitFor();
			} catch (InterruptedException ignore) {
				return;
			}
		}
	}

}
